package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.dto.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.vo.AdminSimpleReforgeCollectionVO;
import com.sc.nft.entity.vo.ecology.*;
import com.sc.nft.enums.CollectionOriginalTypeEnum;
import com.sc.nft.enums.CommodityType;
import com.sc.nft.enums.EcologyExpendType;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.AdminEcologyReforgeConfService;

import com.sc.nft.service.EcologyPointsService;
import com.sc.nft.service.StaticDataService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 生态-重铸-配置 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-06-14
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class AdminEcologyReforgeConfServiceImpl implements AdminEcologyReforgeConfService {


    private final DigitalCollectionProductInfoDao digitalCollectionProductInfoDao;
    private final ProductStockDao productStockDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final EcologyReforgeConfDao ecologyReforgeConfDao;
    private final EquityPropsDao equityPropsDao;
    private final EcologyReforgeExpendConfDao ecologyReforgeExpendConfDao;
    private final UserEcologyReforgeRecordsDao userEcologyReforgeRecordsDao;
    private final UserInfoDao userInfoDao;
    private final UserEcologyReforgeUpperLimitDao userEcologyReforgeUpperLimitDao;
    private final UserEcologyReforgeUpperLimitDetailsDao userEcologyReforgeUpperLimitDetailsDao;
    private final UserEcologyReforgeRecordsDetailsDao userEcologyReforgeRecordsDetailsDao;
    private final EcologyHatchConfDao ecologyHatchConfDao;
    private final UserEcologyHatchRecordsDao userEcologyHatchRecordsDao;
    private final StaticDataService staticDataService;
    private final StaticDataDao staticDataDao;
    private final EcologyPointsService ecologyPointsService;

    /**
     * 新增生态重铸配置
     *
     * @param ecologyReforgeConf
     * @param expendConfList
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addAndUpdateReforgeConf(EcologyReforgeConf ecologyReforgeConf, List<EcologyReforgeExpendConf> expendConfList) {
        if (ecologyReforgeConf.getIsReforgeCondition() && (ecologyReforgeConf.getConditionCollectionId() == null || ecologyReforgeConf.getConditionCollectionId() == 0)) {
            throw new GlobalRunTimeException("请选择重铸条件熔炼藏品");
        }else if (ecologyReforgeConf.getIsReforgeCondition() && ecologyReforgeConf.getConditionCollectionId() != 0) {
            DigitalCollection collection = digitalCollectionDao.getById(ecologyReforgeConf.getConditionCollectionId());
            Assert.notNull(collection, () -> new GlobalRunTimeException("重铸条件熔炼藏品不存在"));
            ecologyReforgeConf.setConditionCollectionName(collection.getFirstTitle());
        }
        if (ObjectUtil.isNull(ecologyReforgeConf.getId())) {
            DigitalCollectionProductInfo product = digitalCollectionProductInfoDao.getById(ecologyReforgeConf.getProductId());
            Assert.notNull(product, () -> new GlobalRunTimeException("商品不存在"));
            Assert.isTrue(product.getCommodityType() == CommodityType.ECOLOGY_REFORGE, () -> new GlobalRunTimeException("商品类型不正确"));

            ProductStock productStock = productStockDao.getByProductId(product.getId());
            Assert.notNull(productStock, () -> new GlobalRunTimeException("商品不存在"));
            Assert.isTrue(productStock.getUsableCount() > 0, () -> new GlobalRunTimeException("商品库存不足"));

            ecologyReforgeConf.setProductName(product.getFirstTitle());

            DigitalCollection collection = digitalCollectionDao.getById(product.getRelationId());
            Assert.notNull(collection, () -> new GlobalRunTimeException("商品不存在"));
            Assert.isTrue(collection.getOriginalType() == CollectionOriginalTypeEnum.MATE_UNIVERSE, () -> new GlobalRunTimeException("玛特钱包的藏品不能添加到熔炼配置"));
            ecologyReforgeConf.setCollectionId(product.getRelationId());
            ecologyReforgeConf.setCollectionName(collection.getFirstTitle());
            ecologyReforgeConf.setSumCount(productStock.getSumCount());
            ecologyReforgeConf.setStatus(ObjectUtil.isNull(ecologyReforgeConf.getStatus()) ? Boolean.FALSE : ecologyReforgeConf.getStatus());
            ecologyReforgeConf.setSort(ObjectUtil.isNull(ecologyReforgeConf.getSort()) ? 0L : ecologyReforgeConf.getSort());
            ecologyReforgeConf.insert();
        } else {
            Assert.isTrue(ecologyReforgeConfDao.updateSortAndRefluxRatioById(ecologyReforgeConf.getId(), ecologyReforgeConf.getSort(),
                    ecologyReforgeConf.getRefluxRatio(),ecologyReforgeConf.getReforgeFreeCount(),ecologyReforgeConf.getIsReforgeCondition(),
                    ecologyReforgeConf.getConditionCollectionId(),ecologyReforgeConf.getConditionCollectionName()), () -> new GlobalRunTimeException("修改配置失败"));
        }

        for (EcologyReforgeExpendConf ecologyReforgeExpendConf : expendConfList) {
            if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.ECOLOGY_POINTS) {//积分
                ecologyReforgeExpendConf.setExpendName(EcologyExpendType.ECOLOGY_POINTS.getDescription());
                ecologyReforgeExpendConf.setExpendImage(EcologyExpendType.ECOLOGY_POINTS.getImage());
            } else if (ecologyReforgeExpendConf.getExpendType() == EcologyExpendType.EQUITY_PROPS){//权益道具
                EquityProps equityProps = equityPropsDao.getById(ecologyReforgeExpendConf.getExpendId());
                Assert.notNull(equityProps, () -> new GlobalRunTimeException("权益道具不存在"));
                ecologyReforgeExpendConf.setExpendName(equityProps.getFirstTitle());
                ecologyReforgeExpendConf.setExpendImage(equityProps.getCreationContent());
            }else {//权益道具
                EcologyPoints ecologyPoints = ecologyPointsService.getById(ecologyReforgeExpendConf.getExpendId());
                Assert.notNull(ecologyPoints, () -> new GlobalRunTimeException("选择积分不存在"));
                ecologyReforgeExpendConf.setExpendName(ecologyPoints.getPointsName());
                ecologyReforgeExpendConf.setExpendImage(ecologyPoints.getPointsImage());
            }
            ecologyReforgeExpendConf.setEcologyReforgeConfId(ecologyReforgeConf.getId());

            if (ObjectUtil.isNull(ecologyReforgeExpendConf.getId())) {
                ecologyReforgeExpendConf.insert();
            } else {
                EcologyReforgeExpendConf getOne = ecologyReforgeExpendConfDao.getOneByIdAndEcologyReforgeConfId(ecologyReforgeExpendConf.getId(), ecologyReforgeExpendConf.getEcologyReforgeConfId());
                Assert.notNull(getOne, () -> new GlobalRunTimeException("生态重铸消耗配置不存在"));
                EcologyReforgeConf reforgeConfInDb = ecologyReforgeConfDao.getById(ecologyReforgeExpendConf.getEcologyReforgeConfId());
                Assert.isFalse(reforgeConfInDb.getStatus(), () -> new GlobalRunTimeException("生态重铸配置已经启用，不可修改"));
                ecologyReforgeExpendConf.updateById();
            }
        }
    }

    /**
     * 分页获取生态重铸配置
     *
     * @param collectionName
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public Page<AdminGetPageReforgeConfVO> getPageReforgeConf(String collectionName, Integer pageNo, Integer pageSize) {
        return ecologyReforgeConfDao.getPageReforgeConf(collectionName, pageNo, pageSize);
    }

    /**
     * 获取生态重铸配置详情
     *
     * @param id
     * @return
     */
    @Override
    public AdminReforgeConfDetailsVO getReforgeConfDetails(Long id) {
        EcologyReforgeConf ecologyReforgeConf = ecologyReforgeConfDao.getById(id);
        Assert.notNull(ecologyReforgeConf, () -> new GlobalRunTimeException("生态重铸配置不存在"));

        AdminReforgeConfDetailsVO adminReforgeConfDetailsVO = BeanUtil.copyProperties(ecologyReforgeConf, AdminReforgeConfDetailsVO.class);
        List<EcologyReforgeExpendConf> list = ecologyReforgeExpendConfDao.getListByEcologyReforgeConfId(ecologyReforgeConf.getId());
        adminReforgeConfDetailsVO.setExpendList(BeanUtil.copyToList(list, AdminReforgeConfExpendDetailsVO.class));
        return adminReforgeConfDetailsVO;
    }

    /**
     * 删除生态重铸消耗配置
     *
     * @param id
     */
    @Override
    public void delExpendById(Long id) {
        EcologyReforgeExpendConf ecologyReforgeExpendConf = ecologyReforgeExpendConfDao.getById(id);
        Assert.notNull(ecologyReforgeExpendConf, () -> new GlobalRunTimeException("生态重铸消耗配置不存在"));

        EcologyReforgeConf ecologyReforgeConf = ecologyReforgeConfDao.getById(ecologyReforgeExpendConf.getEcologyReforgeConfId());
        Assert.notNull(ecologyReforgeConf, () -> new GlobalRunTimeException("生态重铸配置不存在"));
        Assert.isFalse(ecologyReforgeConf.getStatus(), () -> new GlobalRunTimeException("生态重铸配置已经启用，不可修改"));

        Assert.isTrue(ecologyReforgeExpendConfDao.delExpendById(id), () -> new GlobalRunTimeException("删除生态重铸消耗配置更新失败"));
    }

    /**
     * 生态重铸配置上下架
     *
     * @param id
     * @param status
     */
    @Override
    public void updateReforgeConfStatusgById(Long id, Boolean status) {
        EcologyReforgeConf ecologyReforgeConf = ecologyReforgeConfDao.getById(id);
        Assert.notNull(ecologyReforgeConf, () -> new GlobalRunTimeException("生态重铸配置不存在"));

        Assert.isTrue(ecologyReforgeConfDao.updateStatusById(id, status), () -> new GlobalRunTimeException("生态重铸配置状态更新失败"));
    }

    /**
     * 生态重铸配置排序
     *
     * @param id
     * @param sort
     */
    @Override
    public void updateReforgeConfSortById(Long id, Long sort) {
        EcologyReforgeConf ecologyReforgeConf = ecologyReforgeConfDao.getById(id);
        Assert.notNull(ecologyReforgeConf, () -> new GlobalRunTimeException("生态重铸配置不存在"));

        Assert.isTrue(ecologyReforgeConfDao.updateSortById(id, sort), () -> new GlobalRunTimeException("生态重铸配置排序更新失败"));
    }

    /**
     * 删除生态重铸配置
     *
     * @param id
     */
    @Override
    public void delReforgeConfById(Long id) {
        EcologyReforgeConf ecologyReforgeConf = ecologyReforgeConfDao.getById(id);
        Assert.notNull(ecologyReforgeConf, () -> new GlobalRunTimeException("生态重铸配置不存在"));
        Assert.isFalse(ecologyReforgeConf.getStatus(), () -> new GlobalRunTimeException("生态重铸配置已经启用，不可删除"));

        Assert.isTrue(ecologyReforgeConfDao.delReforgeConfById(id), () -> new GlobalRunTimeException("删除生态重铸配置更新失败"));
        Assert.isTrue(ecologyReforgeExpendConfDao.delByEcologyReforgeConfId(id), () -> new GlobalRunTimeException("删除生态重铸消耗配置更新失败"));
    }

    /**
     * 获取用户 生态重铸记录
     *
     * @param collectionName
     * @param userTel
     * @param startTime
     * @param endTime
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public Page<AdminEcologyReforgeUserRecordsVO> getPageUserRecordsRecords(String collectionName, String userTel, String startTime, String endTime, Integer pageNo, Integer pageSize) {
        Long userId = null;
        if (StrUtil.isNotBlank(userTel)) {
            UserInfo userInfo = userInfoDao.getOneByUserTel(userTel);
            if (ObjectUtil.isNull(userInfo)) {
                return new Page<>(pageNo, pageSize);
            }
            userId = userInfo.getId();
        }
        Long collectionId = null;
        if (StrUtil.isNotBlank(collectionName)) {
            DigitalCollection collection = digitalCollectionDao.getByTitle(collectionName);
            if (ObjectUtil.isNull(collection)) {
                return new Page<>(pageNo, pageSize);
            }
            collectionId = collection.getId();
        }
        return userEcologyReforgeRecordsDao.getPageUserRecordsRecords(collectionId, userId, startTime, endTime, pageNo, pageSize);
    }

    /**
     * 获取用户 生态重铸记录 导出
     *
     * @param collectionName
     * @param userTel
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public List<AdminEcologyReforgeUserRecordsVO> getPageUserRecordsExport(String collectionName, String userTel, String startTime, String endTime) {
        Long userId = null;
        if (StrUtil.isNotBlank(userTel)) {
            UserInfo userInfo = userInfoDao.getOneByUserTel(userTel);
            if (ObjectUtil.isNull(userInfo)) {
                return new ArrayList<>();
            }
            userId = userInfo.getId();
        }
        Long collectionId = null;
        if (StrUtil.isNotBlank(collectionName)) {
            DigitalCollection collection = digitalCollectionDao.getByTitle(collectionName);
            if (ObjectUtil.isNull(collection)) {
                return new ArrayList<>();
            }
            collectionId = collection.getId();
        }

        return userEcologyReforgeRecordsDao.getPageUserRecordsExport(collectionId, userId, startTime, endTime);
    }

    /**
     * 用户重铸上限(汇总)
     *
     * @param userTel
     * @return
     */
    @Override
    public List<AdminUserEcologyReforgeUpperLimitDetailsVO> userEcologyReforgeUpperLimitDetails(String userTel) {
        return userEcologyReforgeUpperLimitDao.userEcologyReforgeUpperLimitDetails(userTel);
    }

    /**
     * 用户重铸上限记录(详情)
     *
     * @param userId
     * @param collectionId
     * @param beginTime
     * @param endTime
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public Page<AdminUserEcologyReforgeUpperLimitPageVO> userEcologyReforgeUpperLimitPage(Long userId, Long collectionId, Date beginTime, Date endTime, Integer pageNo, Integer pageSize) {
        return userEcologyReforgeUpperLimitDetailsDao.getUserEcologyReforgeUpperLimitPage(userId, collectionId, beginTime, endTime, pageNo, pageSize);
    }

    /**
     * 获取简单的重铸藏品列表
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public Page<AdminSimpleReforgeCollectionVO> getSimplePage(Integer pageNo, Integer pageSize) {
        return ecologyReforgeConfDao.getSimplePage(pageNo, pageSize);
    }

    /**
     * 时间配置
     *
     * @param startTime
     * @param endTime
     */
    @Override
    public void timeConfig(String startTime, String endTime, String remark) {
        staticDataService.edit("reforge_start_time", startTime, "重铸开始时间");
        staticDataService.edit("reforge_end_time", endTime, "重铸结束时间");
        staticDataService.edit("reforge_remark", remark, "重铸室说明");
    }

    /**
     * 时间配置详情
     *
     * @return
     */
    @Override
    public EcologyReforgeTimeVO timeDetail() {
        EcologyReforgeTimeVO ecologyReforgeTimeVO = new EcologyReforgeTimeVO();
        ecologyReforgeTimeVO.setStartTime(staticDataDao.getByType("reforge_start_time").getValue());
        ecologyReforgeTimeVO.setEndTime(staticDataDao.getByType("reforge_end_time").getValue());
        ecologyReforgeTimeVO.setRemark(staticDataDao.getByType("reforge_remark").getValue());
        return ecologyReforgeTimeVO;
    }
}
